# nullable enable

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Magicodes.ExporterAndImporter.Core;
using Magicodes.ExporterAndImporter.Excel;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using PHMEE.Diagnosis;
using PHMEE.DTOS.Diagnosis;
using PHMEE.Entities.Diagnosis;
using PHMEE.IServices.Diagnosis;
using Volo.Abp;
using Volo.Abp.Domain.Repositories;

namespace PHMEE.Services.Diagnosis;

public class AlarmReportAppService : PHMEEAppService, IAlarmReportAppService
{
    private readonly IReadOnlyRepository<AlarmRecord, Guid> _alarmRecordRepository;
    private readonly IReadOnlyRepository<Unit, Guid> _unitRepository;
    private readonly IHttpContextAccessor _httpContextAccessor;

    public AlarmReportAppService(
        IReadOnlyRepository<AlarmRecord, Guid> alarmRecordRepository,
        IReadOnlyRepository<Unit, Guid> unitRepository,
        IHttpContextAccessor httpContextAccessor)
    {
        _alarmRecordRepository = alarmRecordRepository;
        _unitRepository = unitRepository;
        _httpContextAccessor = httpContextAccessor;
    }

    /// <inheritdoc />
    public async Task<List<AlarmStatisticsDto>> GetAlarmStatisticsAsync(AlarmStatisticsRequestDto input)
    {
        if (input.StartDateTime > input.EndDateTime)
        {
            throw new UserFriendlyException(L[DiagnosisErrorCodes.DiagStartTimeLaterThanEndTime], DiagnosisErrorCodes.DiagStartTimeLaterThanEndTime);
        }

        var queryable = await _alarmRecordRepository.GetQueryableAsync();
        
        var query = from ar in queryable
            join unit in await _unitRepository.GetQueryableAsync() 
                on ar.UnitId equals unit.Id into unitGroup
            from unit in unitGroup.DefaultIfEmpty()
            where ar.AlarmTimeUtc >= input.StartDateTime && ar.AlarmTimeUtc <= input.EndDateTime
            select new
            {
                AlarmRecord = ar,
                UnitId = ar.UnitId,
                UnitName = unit.DisplayName,
                Area = unit.Area
            };
            
        var records = await query.ToListAsync();
        
        // 根据机组进行分组
        var groupedRecords = records.GroupBy(x => x.UnitId).ToArray();

        // 创建统计结果
        List<AlarmStatisticsDto> result = [];

        foreach (var group in groupedRecords)
        {
            result.Add(new AlarmStatisticsDto
            {
                UnitId = group.Key,
                UnitName = group.First().UnitName,
                Area = group.First().Area,
                CLevelCount = group.Count(x => x.AlarmRecord.FeatureAlarmLevels.ContainsValue(AlarmLevel.C)),
                DLevelCount = group.Count(x => x.AlarmRecord.FeatureAlarmLevels.ContainsValue(AlarmLevel.D)),
                // 目前取不到开机时间和停机时间，返回 null
                RunningTimeInDays = null,
                StopTimeInDays = null
            });
        }

        return result;
    }
    
    /// <inheritdoc />
    public async Task<(MemoryStream stream, string fileName)> ExportAlarmReportAsync(AlarmStatisticsRequestDto input)
    {
        var alarmStatistics = await GetAlarmStatisticsAsync(input);
        
        var exportDto = new AlarmReportExportDto
        {
            StartDateTime = input.StartDateTime.ToString("yyyy-MM-ddTHH:mm:ssZ"),
            EndDateTime = input.EndDateTime.ToString("yyyy-MM-ddTHH:mm:ssZ"),
            AlarmStatistics = alarmStatistics
        };
        
        string templatePath;
        string fileName;
        
        var currentCulture = _httpContextAccessor.HttpContext?.Features
            .Get<Microsoft.AspNetCore.Localization.IRequestCultureFeature>()
            ?.RequestCulture.Culture;
            
        var assemblyPath = Assembly.GetExecutingAssembly().Location;
        var currentDirectory = Path.GetDirectoryName(assemblyPath);
        if (currentDirectory == null)
        {
            throw new Exception("currentDirectory is null");
        }
        
        // 如果为英文，则选择英文报表模板
        if (currentCulture?.Name == "en-US")
        {
            // 英文模板路径
            templatePath = Path.Combine(currentDirectory, "Templates", "AlarmReport_en_us.xlsx");
            fileName = $"alarm_statistic_report_{input.StartDateTime:yyyy-MM-ddTHH-mm-ssZ}_{input.EndDateTime:yyyy-MM-ddTHH-mm-ssZ}.xlsx";
        }
        else
        {
            // 中文模板路径，默认中文
            templatePath = Path.Combine(currentDirectory, "Templates", "AlarmReport_zh_hans.xlsx");
            fileName = $"报警统计报表_{input.StartDateTime:yyyy-MM-ddTHH-mm-ssZ}_{input.EndDateTime:yyyy-MM-ddTHH-mm-ssZ}.xlsx";
        }
        
        IExportFileByTemplate exporter = new ExcelExporter();
        
        var resultBytes = await exporter.ExportBytesByTemplate(exportDto, templatePath);

        return (new MemoryStream(resultBytes), fileName);
    }

}